package com.cn.controller;

import com.cn.baseModel.DataResponse;
import com.cn.entity.User;
import com.cn.service.FileService;
import com.cn.service.UserService;
import com.cn.util.JWTUtil;
import com.cn.util.ScheduleUtil;
import com.cn.util.ThreadUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.var;
import net.sf.jmimemagic.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/index")
@Api(tags = "无需token验证的类")
public class IndexController {
    @Resource
    UserService userService;

    @Resource
    FileService fileService;

    @Resource
    Executor asyncExecutor;

    @Value("${file.path}")
    String filePath;

    @Resource
    ThreadUtil threadUtil;

    @Resource
    ScheduleUtil scheduleUtil;

    /**
     * 登录验证
     *
     * @param user 用户信息
     * @return
     */
    @ApiOperation(value = "用户登录", notes = "登录+发放token")
    @PostMapping("/loginValid")
    public DataResponse loginValid(@RequestBody User user,
                                   HttpServletResponse response) {
        user = userService.getUserByName(user.getUserName(), user.getPassword());
        if (user == null) {
            return DataResponse.error("用户名密码错误", "-1");
        }
        String token = JWTUtil.createToken(user.getId().toString(), user.getPassword());
        response.setHeader("token", token);
        return DataResponse.success(user);
    }

    /**
     * 下载功能测试
     *
     * @return
     */
    @ApiOperation(value = "下载接口", notes = "下载接口")
    @PostMapping("/download")
    public ResponseEntity download(HttpServletRequest request) {
        UrlResource resource = fileService.loadFileAsResource(filePath);
        String contentType = null;

        try {
            //contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
            MagicMatch magicMatch = Magic.getMagicMatch(resource.getFile(), true, false);
            contentType = magicMatch.getMimeType();
        } catch (IOException e) {
            System.out.print("无法获取文件类型");
        } catch (MagicException e) {
            e.printStackTrace();
        } catch (MagicParseException e) {
            e.printStackTrace();
        } catch (MagicMatchNotFoundException e) {
            e.printStackTrace();
        }

        return ResponseEntity.ok()
                .contentType(MediaType.valueOf(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + resource.getFilename() + "")
                .body(resource);
    }

    /**
     * 文件上传
     *
     * @param file 上
     * @return DataResponse
     */
    @ApiOperation(value = "文件上传", notes = "文件上传")
    @PostMapping("/upload")
    public DataResponse upload(@RequestPart MultipartFile file) {
        File newFile = new File(filePath);
        try {
            Files.copy(file.getInputStream(), newFile.toPath());
        } catch (IOException e) {
            return DataResponse.error(e.getMessage(), "91");
        }
        return DataResponse.success("成功");
    }

    /**
     * 测试线程池
     */
    @ApiOperation(value = "线程测试", notes = "线程测试")
    @GetMapping("/getThread1")
    public void getThread1() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
        List<CompletableFuture<Integer>> collect = list.stream().map(
                n -> threadUtil.dealNum(n)
        ).collect(Collectors.toList());

        System.out.println(collect.stream().map(CompletableFuture::join).collect(Collectors.toList()));
    }

    /**
     * 测试线程池2
     */
    @ApiOperation(value = "线程测试", notes = "线程测试")
    @GetMapping("/getThread2")
    public void getThread2() {
        List<Integer> list = Arrays.asList(1, 2, 3);
        CompletionService completionService = new ExecutorCompletionService(asyncExecutor);
        for (Integer i : list) {
            completionService.submit(() -> {
                Thread.sleep(1000 * (3 - i));
                return i * 2;
            });
        }
        try {
            for (Integer i : list) {
               Future future = completionService.poll(10,TimeUnit.SECONDS);
                if (future != null) {
                    System.out.println(future.get());
                } else {
                    // 在此处处理超过6分钟的情况
                }
            }
        } catch (InterruptedException | ExecutionException e) {

        }

    }

    /**
     * 测试线程池3
     */
    @ApiOperation(value = "线程测试", notes = "线程测试")
    @GetMapping("/getThread3")
    public void getThread3() {
        List<Integer> list = Arrays.asList(1, 2, 3);

        List<CompletableFuture<Integer>> integers = list.stream().map(
               i->CompletableFuture.supplyAsync(()->{
                   try {
                       Thread.sleep(1000 * (3 - i));
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   return i * 2;
               },asyncExecutor)).collect(Collectors.toList());
        //等待所有线程执行完毕
        CompletableFuture.allOf(integers.toArray(new CompletableFuture[0])).join();
        //处理结果
        List<Integer> result = integers.stream().map(CompletableFuture::join).collect(Collectors.toList());
        System.out.println(result);

    }

    /**
     * 测试线程池3
     */
    @ApiOperation(value = "定时任务", notes = "定时任务")
    @GetMapping("/getSchedule")
    public void getSchedule() {
        scheduleUtil.startTask();
    }
}
